package edu.se.jai.lesson04guess2.config;

import edu.se.jai.lesson04guess2.model.entity.GameRoom;
import edu.se.jai.lesson04guess2.service.GameService;
import edu.se.jai.lesson04guess2.service.MessageSend;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;

/**
 * WebSocket事件监听器
 * 
 * 负责处理WebSocket连接事件，包括：
 * - 连接断开时的数据清理
 * - 房间创建者断线时自动解散房间
 * - 普通玩家断线时自动离开房间
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WebSocketEventListener {

    private final GameService gameService;
    private final MessageSend messageSend;

    /**
     * 处理WebSocket连接断开事件
     * 
     * @param event 连接断开事件
     */
    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = headerAccessor.getSessionId();

        log.info("WebSocket连接断开 - Session ID: {}", sessionId);

        // 1. 获取玩家所在的房间ID
        GameRoom room = gameService.getRoomBySessionId(sessionId);

        if (room != null) {
            // 2. 判断玩家是否为房间创建者
            if (room.getCreatorSessionId().equals(sessionId)) {
                // 3. 如果是创建者：解散房间并发送解散房间消息
                log.info("房间创建者 {} 断线，解散房间 {}，原房间人数: {}", sessionId, room.getRoomId(), room.getPlayers().size());
                gameService.dissolveRoom(sessionId, room.getRoomId());
                //发送解散房间消息
                messageSend.notifyRoomDissolved(room);
            } else {
                // 3. 如果是参与者：离开房间并发送离开房间消息以及房间内容更新消息
                log.info("玩家 {} 断线，离开房间 {}，原房间人数: {}", sessionId, room.getRoomId(), room.getPlayers().size());
                gameService.leaveRoom(sessionId, room.getRoomId());

                // 先发送离开消息给房间内其他玩家
                messageSend.notifyLeave(room, sessionId);

                // 再发送房间更新消息
                messageSend.notifyRoomUpdate(room);
            }
            log.info("已清理断线玩家数据 - Session ID: {}", sessionId);
        } else {
            log.info("断线玩家不在任何房间中 - Session ID: {}", sessionId);
        }
    }

}
